package com.yunxin.customui.util;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.yunxin.tools.commonbean.exceptions.GeneralException;
import com.yunxin.tools.commonbean.exceptions.MyExceptionSupplier;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 自定义sql，解析占位符SQL等工具
 *
 * @author LGY
 * @date 2021/10/20
 */
public class CustomSQLUtil {

    /**
     * 左大括号
     */
    private static final byte left_big_bracket = 123;
    /**
     * 右大括号
     */
    private static final byte right_big_bracket = 125;

    /**
     * 左中括号
     */
    private static final byte left_middle_bracket = 91;
    /**
     * 右中括号
     */
    private static final byte right_middle_bracket = 93;

    /**
     * 跳过条件
     */
    private static final String skip_condition = "1=1";
    /**
     * 必须条件标志
     */
    private static final String must_flag = "!";
    /**
     * 构建sql
     *
     * @param old_sql 旧sql
     * @param params  参数
     * @return {@link String}
     */
    public static String buildSQL(String old_sql, Map<String,Object> params){

        //解析map,替换占位符
        List<String> old_conditions = getFlag(old_sql, left_big_bracket, right_big_bracket);
        for (String bigFlag: old_conditions) {
            //判断占位符中有没有!
            boolean mustFlag = bigFlag.contains(must_flag);
            List<String> middle_flag = getFlag(bigFlag, left_middle_bracket, right_middle_bracket);
            Assert.notEmpty(middle_flag,new MyExceptionSupplier<>(new GeneralException("解析占位符出错，请检查占位符:"+middle_flag)));
            for (int i = 0; i < middle_flag.size(); i++) {
                String param = String.valueOf(params.get(middle_flag.get(i).replaceFirst("\\[","").replaceFirst("]","").trim()));
                if (param == null || ObjectUtil.equals("null",param)){
                    if (mustFlag){
                        throw new GeneralException("占位符必要字段未在参数中找到："+middle_flag.get(0));
                    }else {
                        old_sql = old_sql.replace(bigFlag,skip_condition);
                    }
                }else {
                    String new_condition = bigFlag.replace("!","").replace("{","")
                            .replace("}","").replace(middle_flag.get(i),"'"+param+"'");
                    old_sql = old_sql.replace(bigFlag,new_condition);
                    bigFlag = new_condition;
                }
            }

        }
        return old_sql.replace("\\r"," ").replace("\\t"," ").replace("\\n"," ");
    }


    /**
     * 获取执行的占位符子字符串集合
     *
     * @param str   字符串
     * @param left_flag  左标志
     * @param right_flag 右标志
     * @return {@link List<String>}
     */
    public static List<String> getFlag(String str , byte left_flag, byte right_flag){
        char[] chars = str.toCharArray();
        List<String> stringList = new ArrayList<>();
        short bIndex = 0;
        for (short i = 0; i < chars.length; i++) {
            if (chars[i] == left_flag){
                Assert.isTrue(bIndex<=0,new MyExceptionSupplier<>(new GeneralException("请检查检查字符串1:"+str)));
                bIndex = i;
            }else if (chars[i] == right_flag) {
                Assert.isTrue(bIndex>0,new MyExceptionSupplier<>(new GeneralException("请检查检查字符串2:"+str)));
                stringList.add(str.substring(bIndex, i+1));
                bIndex=-1;
            }
        }
        Assert.isTrue(bIndex<=0,new MyExceptionSupplier<>(new GeneralException("请检查检查字符串3:"+str)));
        return stringList;
    }
}
